
#include "member_BScrollBar.h"
#include "member_BWidget.h"

using namespace BWE;

member_BScrollBar::member_BScrollBar(BScrollBar* scrollBar)
{
	boss = scrollBar;
	value = 0;
	page = 10;
	range.set(0, 100);
	step = 1;
	handleSize = 0;
	orientation = Orientation_Horizontal;
	pressed = false;
	draging = false;
	hoverHandle = false;
	dirty = true;
	autoTop = true;
	autoLeft = true;
	autoRight = true;
	autoBottom = true;
}
member_BScrollBar::~member_BScrollBar()
{

}

void member_BScrollBar::freshRects()
{
	BPerch perch = boss->perch();
	if (orientation & Orientation_Horizontal)
	{
		if (decreaseButton && autoLeft)
		{
			BSize sizeHint = decreaseButton->sizeHint();
			sizeHint = decreaseButton->sizeLimit(sizeHint);
			perch.left() = sizeHint.width();
		}
		if (increaseButton)
		{
			BSize sizeHint = increaseButton->sizeHint();
			sizeHint = increaseButton->sizeLimit(sizeHint);
			perch.right() = sizeHint.width();
		}
	}
	if (orientation & Orientation_Vertical)
	{
		if (decreaseButton)
		{
			BSize sizeHint = decreaseButton->sizeHint();
			sizeHint = decreaseButton->sizeLimit(sizeHint);
			perch.bottom() = sizeHint.height();
		}
		if (increaseButton)
		{
			BSize sizeHint = increaseButton->sizeHint();
			sizeHint = increaseButton->sizeLimit(sizeHint);
			perch.top() = sizeHint.height();
		}
	}
	boss->setPerch(perch);

	const BFont* font = boss->realFont();
	BMargin marign = boss->margin();
	BRect crect = boss->centerRect();
	int cw = crect.width();
	int ch = crect.height();

	BSize realHandleSize = handleSize;
	if (realHandleSize.width() < 1)
		realHandleSize.width() = cw;
	if (realHandleSize.height() < 1)
		realHandleSize.height() = ch;

	if (page > range.size())
		page = range.size();
	if (value < range.min())
		value = range.min();
	if (value > range.max() - page)
		value = range.max() - page;

	float rangeSize = float(range.size());
	if (rangeSize > 0)
	{
		if (orientation & Orientation_Horizontal)
		{
			int handleHeight = realHandleSize.height();
			if (handleHeight > ch)
				handleHeight = ch;
			int handleWidth = (int)(cw * page / rangeSize);
			if (handleWidth < 10)
				handleWidth = 10;
			int valuePos = int(cw * (value - range.min()) / rangeSize);
			int x = crect.left() + valuePos;
			if (orientation & Orientation_Reverse)
				x = crect.right() - valuePos - handleWidth;
			int y = crect.top() + (ch - handleHeight) / 2;
			handleRect.set(x, y, handleWidth, handleHeight);
			if (decreaseButton)
			{
				BRect leftRect = boss->rect(Part_Left);
				decreaseButton->setRect(leftRect);
			}
			if (increaseButton)
			{
				BRect rightRect = boss->rect(Part_Right);
				increaseButton->setRect(rightRect);
			}
		}
		if (orientation & Orientation_Vertical)
		{
			int handleWidth = realHandleSize.width();
			if (handleWidth > cw)
				handleWidth = cw;
			int x = crect.x() + (cw - handleWidth) / 2;
			int y = (int)(crect.top() + ch * (value - range.min()) / rangeSize);
			if (orientation & Orientation_Reverse)
				y = (int)(crect.bottom() - cw * (value - range.min()) / rangeSize);
			int handleHeight = (int)(ch * page / rangeSize);
			if (handleHeight < 10)
				handleHeight = 10;
			handleRect.set(crect.x(), y, handleWidth, handleHeight);
			if (decreaseButton)
			{
				BRect topRect = boss->rect(Part_Top);
				decreaseButton->setRect(topRect);
			}
			if (increaseButton)
			{
				BRect bottomRect = boss->rect(Part_Bottom);
				increaseButton->setRect(bottomRect);
			}
		}
	}

	if (IRound* round = widget_member(boss)->round)
	{
		handlePoints.reset();
		round->createInnerPoints(crect, handleRect, handlePoints);
	}
	else
	{
		handlePoints.clear();
	}
}

void member_BScrollBar::slotButtonClicked(BObject* object)
{
	int change = 0;
	if (object == decreaseButton)
	{
		change = -step;
	}
	if (object == increaseButton)
	{
		change = step;
	}
	if (orientation & Orientation_Reverse)
		change = -change;
	if (change)
	{
		boss->setValue(value + change);
		boss->emit(Signal_ValueEdited, value);
		boss->emit(Signal_EditFinished, value);
	}
}
